﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;


namespace 营救宠物
{
    public class toolFunctions
    {

        //=======================================================
        //块的绘制与擦除
        //=======================================================

        /// <summary>
        /// 绘制棋盘格,M行N列,绘制像素起点(offX, offY),方格宽度width
        /// </summary>
        public void drawQipan(Graphics g, int M, int N, int offX, int offY, int width)
        {
            drawQipan(g, M, N, offX, offY, width, width); 

        }
        public void drawQipan(Graphics g, int M, int N, int offX, int offY, int width, int height)
        {
            Pen pen1 = new Pen(Color.Black, 2);                                         //创建画笔，用于绘制方格

            if (pen1 != null)
            {
                pen1.Width = 2;
                g.DrawRectangle(pen1, offX, offY, width * N + 1, height * M + 1);         //绘制外边框，附加1个像素

                pen1.Width = 1;
                for (int i = 1; i <= M - 1; i++)                                         //绘制行
                    g.DrawLine(pen1, offX, height * i + offY, offX + width * N, height * i + offY);
                for (int i = 1; i <= N - 1; i++)                                         //绘制列
                    g.DrawLine(pen1, offX + width * i, offY, offX + width * i, height * M + offY);
            }
        }

        /// <summary>
        /// 在g对象，区域Rect中，坐标(x行,y列)处，绘制图像pic，
        /// 行列起点0，绘制块大小为width
        /// </summary>
        public void drawPic(Graphics g, Rectangle Rect, int x, int y, Image pic, int width)
        {
            drawPic(g, Rect, x, y, pic, width, width);
        }
        public void drawPic(Graphics g, Rectangle Rect, int x, int y, Image pic, int width, int height)
        {
            Point p = new Point(Rect.X + y * width, Rect.Y + x * height);    //行列位置转化为像素位置
            g.DrawImage(pic, p.X + 1, p.Y + 1, width - 1, width - 1);       //在对应位置绘制图像，偏移减小一个像素避开棋盘线
        }
        public void drawPic_2(Graphics g, Rectangle Rect, int x, int y, Image pic, int width, int height)
        {
            Point p = new Point(Rect.X + y * width, Rect.Y + x * height);    //行列位置转化为像素位置
            g.DrawImage(pic, p.X + 1, p.Y + 1, width - 1, height - 1);       //在对应位置绘制图像，偏移减小一个像素避开棋盘线
        }

        /// <summary>
        /// 在TileMap区域坐标(x行,y列)处,绘制数值num, C标识是否为传送绘制
        /// 行列起点0，绘制块大小为width
        /// </summary>
        public void drawNumber(Graphics g, Rectangle Rect, int x, int y, int num, int numWidth, int width, int height)
        {
            Font drawFont = new Font("Arial", numWidth);
            SolidBrush drawBrush = new SolidBrush(Color.White);
            Point p = new Point(Rect.X + y * width, Rect.Y + (x + 1) * height - (int)(numWidth * 1.5));  //行列位置转化为像素位置
            g.DrawString(num.ToString(), drawFont, drawBrush, p);                   //绘制对应的字符串
        }

        /// <summary>
        /// 擦除rect区域中坐标(x行,y列)处的图像
        /// </summary>
        /// 
        public void eraserPic(Image background, int RealWidth, int RealHeight, Graphics g, Rectangle rect, int width, int x, int y)
        {
            eraserPic(background, RealWidth, RealHeight, g, rect, width, width, x, y);
        }
        public void eraserPic(Image background, int RealWidth, int RealHeight, Graphics g, Rectangle rect, int width, int height, int x, int y)
        {
            double reSizeW = background.Width / (double)RealWidth;                  //计算背景的缩放比例
            double reSizeH = background.Height / (double)RealHeight;

            Point p = new Point(rect.X + y * width + 1, rect.Y + x * height + 1);   //行列位置转化为像素位置，不包含棋盘线的1个像素
            Rectangle destRect = new Rectangle(p, new Size(width - 1, height - 1)); //绘制目标区域

            Point p2 = new Point((int)(p.X * reSizeW), (int)(p.Y * reSizeH));
            Size s2 = new Size((int)(width * reSizeW), (int)(height * reSizeH));
            Rectangle srcRect = new Rectangle(p2, s2);                              //绘制图像源区域

            g.DrawImage(background, destRect, srcRect, GraphicsUnit.Pixel);         //使用背景图像重绘目标区域
            //g.DrawImage(pic, p.X, p.Y, width, width);       //在对应位置绘制图像
        }


        //=======================================================
        //块数据合并与解析
        //=======================================================
        /// <summary>
        /// 将块数据data合并到srcData中
        /// </summary>
        public int DataAdd(int data, int srcData)
        {
            int[] tmp = DataSplit(srcData);//先对块数据进行解析

            for (int i = 0; i < tmp.Length; i++)
            {
                //if ((int)(tmp[i] / 10) == 1)    //若为第一行块，同类型不替换 
                //{
                //    if (tmp[i] == data) return srcData;
                //}
                //要合并的数据中含有同种类型的块数据，则替换
                //else if ((int)(tmp[i] / 10) == (int)(data / 10))
                if ((int)(tmp[i] / 10) == (int)(data / 10))
                {
                    tmp[i] = data;              //替换同类型的块数据
                    return DataAdd(tmp);        //重新合并为一个数据
                }
            }

            //没有同类型的块，则转存到新的数组中
            if (tmp.Length == 5) return srcData;//整型数据存储，仅允许最大2*5位数据，5层叠加

            int[] array = new int[tmp.Length + 1];
            Array.Copy(tmp, 0, array, 0, tmp.Length);
            array[tmp.Length] = data;

            return DataAdd(array);              //返回合并后的数据
        }

        /// <summary>
        /// 将array中的数据合并为一个整型数据
        /// </summary>
        public int DataAdd(int[] array)
        {
            if (array.Length > 1) Array.Sort(array);

            int data = 0;
            for (int i = 0; i < array.Length; i++)
                data = data * 100 + array[i];

            return data;
        }

        /// <summary>
        /// 对块数据data 进行分割解析
        /// </summary>
        public int[] DataSplit(int data)
        {
            int[] tmp = new int[10];
            int len = 0;

            while (data > 0)                //解析data中的数据到块，每两位标识一个块
            {
                tmp[len++] = data % 100;
                data /= 100;
            }

            if (len == 0)
            {
                int[] array = new int[1];
                array[0] = 0;
                return array;               //没有数据，则返回0
            }
            else
            {
                //解析后的数据转存到新的数组，并排序
                int[] array = new int[len];
                Array.Copy(tmp, 0, array, 0, len);
                Array.Sort(array);

                return array;
            }
        }

        /// <summary>
        /// 判断数据srcData中，是否含有data对应块
        /// </summary>
        public bool Contains(int data, int srcData)
        {
            int[] tmp = DataSplit(srcData);
            for (int i = 0; i < tmp.Length; i++)
                if (tmp[i] == data) return true;
            return false;
        }

        /// <summary>
        /// 从数据srcData中，减去data对应块数据
        /// </summary>
        public int DataSub(int data, int srcData) 
        {
            int[] tmp = DataSplit(srcData);         //分割数据为块属性
            
            for (int i = 0; i < tmp.Length; i++)
            {
                if (tmp[i] == data)                 //剔除data块属性
                {
                    int[] array = new int[tmp.Length - 1];
                    if (i > 0) 
                        Array.Copy(tmp, 0, array, 0, i);
                    if(i < tmp.Length-1)
                        Array.Copy(tmp, i + 1, array, i, array.Length - i);
                    return DataAdd(array);
                }
            }
            return srcData;
        }

        //=======================================================
        //Json串的输出
        //=======================================================
        /// <summary>
        /// 将一维数组中的数据，转化为JsonArray样式的字符串
        /// 形如：[0,1,0,1,1]
        /// </summary>
        public string ToJsonArray(int[] data)
        {
            string str = "[";
            for (int i = 0; i < data.Length; i++)
                str += data[i] + (i == data.Length - 1 ? "" : ",");
            str += "]";

            return str;
        }

        /// <summary>
        /// 将二维数组中的数据，转化为JsonArray样式的字符串
        /// 形如：[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]
        /// </summary>
        public string ToJsonArray(int[][] data)
        {
            string str = "[";
            if (data != null)
            {
                for (int i = 0; i < data.Length; i++)
                    str += ToJsonArray(data[i]) + (i == data.Length - 1 ? "" : ",");
            }
            str += "]";

            return str;
        }

        /// <summary>
        /// 将三维数组中的数据，转化为JsonArray样式的字符串
        /// 形如：[[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]],[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]],[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]]
        /// </summary>
        public string ToJsonArray(int[][][] data)
        {
            string str = "[";
            for (int i = 0; i < data.Length; i++)
                str += ToJsonArray(data[i]) + (i == data.Length - 1 ? "" : ",");
            str += "]";

            return str;
        }

        /// <summary>
        /// 将Json字符串，转化为Json字符串项
        /// 形如："mapData":[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]] 或 "name":"classic"
        /// </summary>
        public string ToJsonIteam(string IteamName, string JsonStr)
        {
            string str = "\"" + IteamName + "\":";

            if (JsonStr.Length > 0 && JsonStr[0].Equals('[')) str += JsonStr;
            else str += "\"" + JsonStr + "\""; 

            return str;
        }
        /// <summary>
        /// 将数组数据，和名称转化为Json字符串项
        /// </summary>
        public string ToJsonIteam(string IteamName, int[] data)
        { return ToJsonIteam(IteamName, ToJsonArray(data));}
        public string ToJsonIteam(string IteamName, int[][] data)
        { return ToJsonIteam(IteamName, ToJsonArray(data)); }
        public string ToJsonIteam(string IteamName, int[][][] data)
        { return ToJsonIteam(IteamName, ToJsonArray(data)); }

        /// <summary>
        /// 将整型数据，转化为Json字符串项
        /// 形如："number":6 
        /// </summary>
        public string ToJsonIteam(string IteamName, int num)
        {
            string str = "\"" + IteamName + "\":" + num;
            return str;
        }


        //按给定分隔符，将一维字符串数组合并为一个字符串
        public string ToString(string[]data, string seprator)
        {
            string str = "";

            if (data == null) return str;
            for (int i = 0; i < data.Length; i++)
            {
                str += (i==0 ? "" : seprator) + data[i];
            }
            return str;
        }

        //按给定分隔符，将二维字符串数组合并为一个字符串
        public string ToString(string[][] data, string seprator2, string seprator1)
        {
            string str = "";
            for (int i = 0; i < data.Length; i++)
            {
                str += (i==0 ? "" : seprator2) + ToString(data[i], seprator1);
            }
            return str;
        }

        //将二维字符串数组合并为一个串，做为一个Json项
        public string ToJsonIteam(string IteamName, string[][] data)
        {
            string str = ToString(data, ";", ",");
            return ToJsonIteam(IteamName, str);
        }

        //将字符串数据按给定的分隔符，分割为二维字符串数组
        public string[][] Split(string data, char seprator2, char seprator1)
        {
            string[] tmp = data.Split(seprator2);

            string[][] str = new string[tmp.Length][];
            for (int i = 0; i < str.Length; i++)
                str[i] = tmp[i].Split(seprator1);

            return str;
        }

        /// <summary>
        /// 将Json字符串项，封装为Json对象串
        /// 形如：{"gameMode":"Classic","mapData":[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]}
        /// </summary>
        public string ToJsonObj(string[] JsonData)
        {
            string str = "{";
            for (int i = 0; i < JsonData.Length; i++)
                str += JsonData[i] + (i == JsonData.Length - 1 ? "" : ",");
            str += "}";

            return str;
        }

        /// <summary>
        /// 将二维数组数据转化为Json对象串
        /// </summary>
        public string ToJson(string IteamName, int[][] data)
        {
            string JsonStr = ToJsonArray(data);

            //string strIteam2 = ToJsonIteam("gameMode", "Classic");
            //string strIteam3 = ToJsonIteam("number", 7);

            string strIteam1 = ToJsonIteam(IteamName, JsonStr);
            string Json = ToJsonObj(new string[] {strIteam1 });
            //string Json = JsonIteamToJson(new string[] { strIteam2, strIteam3, strIteam1 });

            return Json;
        }

        //=======================================================
        //Json串的输入
        //=======================================================
        /// <summary>
        /// 从Json数据串中，获取名称为IteamName的数据串
        /// </summary>
        public string getJsonNodeData(string Json, string NodeName)
        {
            string str = "";
            string[] tmp1, tmp2;
            int postion;

            //Json数据串形如：{"gameMode":"Classic","mapData":[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]}
            if (Json.Contains('{') && Json.Contains('}') && Json.Contains(':'))   
            {
                tmp1 = Json.Split(':');                     //分割
                for (int i = 0; i < tmp1.Length - 1; i++)
                {
                    tmp2 = tmp1[i].Split('"');              //再次分割

                    //获得属性名
                    str = tmp2[tmp2.Length - 2].Trim();     

                    if (str.Equals(NodeName))
                    {
                        tmp2 = tmp1[i + 1].Split('"');                  //分割下一个串
                        postion = tmp1[i + 1][0].Equals('"') ? 1 : 0;   //取下一个串有效数据部分

                        //获取目标串
                        str = tmp2[postion].Trim();                     

                        //去除串尾 } 或 ，
                        if (str[str.Length - 1].Equals('}')) str = str.Substring(0, str.Length - 1);
                        if (str[str.Length - 1].Equals(',') && postion == 0)    //仅去除非""内部的，
                            str = str.Substring(0, str.Length - 1);

                        return str;                         //获取串Classic 或 [[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]
                    }
                    str = "";
                }
            }
            return str;
        }

        /// <summary>
        /// 将一维JsonArray样式的字符串，转化为数组数据
        /// 形如：[0,1,0,1,1]
        /// </summary>
        public int[] ToArray1(string JsonArray)
        {
            JsonArray = JsonArray.Trim();
            JsonArray = JsonArray.TrimStart('[');   //去除串前'['
            JsonArray = JsonArray.TrimEnd(']');     //去除串后']'

            //转化为数值
            string[] str = JsonArray.Split(',');                        //分割数据项
            int[] num = new int[str.Length];

            for (int i = 0; i < str.Length; i++)
            {
                str[i] = str[i].Trim();
                num[i] = Math.Abs(str[i].Equals("") ? 0 : Int32.Parse(str[i]));      
            }

            return num;
        }

        /// <summary>
        /// 将二维JsonArray样式的字符串，转化为数组数据
        /// 形如：[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]
        /// </summary>
        public int[][] ToArray2(string JsonArray)
        {
            JsonArray = JsonArray.Trim();
            JsonArray = JsonArray.TrimStart('[');   //去除串前'['
            JsonArray = JsonArray.TrimEnd(']'); ;   //去除串后']'

            //转化为数值
            JsonArray = JsonArray.Replace("],[", ";");  //替换
            string[] str = JsonArray.Split(';');        //分割数据项
            int[][] num = new int[str.Length][];

            for (int i = 0; i < str.Length; i++)    //一维Json串，转化为数组
                num[i] = ToArray1(str[i]);

            return num;
        }

        /// <summary>
        /// 将三维JsonArray样式的字符串，转化为数组数据
        /// 形如：[[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]],[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]],[[0,1,0,1,1],[0,1,0,1,1],[0,1,0,1,1]]]
        /// </summary>
        public int[][][] ToArray3(string JsonArray)
        {
            JsonArray = JsonArray.Trim();
            JsonArray = JsonArray.TrimStart('[');   //去除串前'['
            JsonArray = JsonArray.TrimEnd(']'); ;   //去除串后']'

            //转化为数值
            JsonArray = JsonArray.Replace("]],[[", ";");    //替换
            string[] str = JsonArray.Split(';');            //分割数据项
            int[][][] num = new int[str.Length][][];

            for (int i = 0; i < str.Length; i++)    //二维Json串，转化为数组
                num[i] = ToArray2(str[i]);

            return num;
        }

        //=======================================================
        //保存数据到文件
        //=======================================================
        /// <summary>
        /// 保存数据data到文件，返回值为保存的文件名
        /// </summary>
        public string SaveToFile(String data, String name, bool mute)
        {
            String filePath = "";

            //若未命名，则使用系统时间自动命名
            if (name == null || name.Trim().Equals("（重命名）") || name.Trim().Equals(""))
            {
                name = DateTime.Now.ToLongTimeString().Replace(":", ".");   //使用系统时间自动为文件命名
                filePath = SaveToFile(data, name, false);                   //保存数据到文件
                return filePath;                                            //返回保存的文件名
            }

            try
            {
                filePath = SaveProcess(data, name);                         //保存数据并记录文件完整路径

                if (!mute) MessageBox.Show("成功导出数据到:“" + filePath + "”!");
                return filePath;
            }
            catch (Exception)
            {
                MessageBox.Show("保存数据失败");
                return "";
            }
        }

        /// <summary>
        /// 保存数据data到文件处理过程，返回值为保存的文件名
        /// </summary>
        public String SaveProcess(String data, String name)
        {
            string CurDir = System.AppDomain.CurrentDomain.BaseDirectory + DateTime.Now.Date.ToString("yyyy_MM_dd") + @"(营救宠物)导出\";         //设置当前目录
            if (!System.IO.Directory.Exists(CurDir)) System.IO.Directory.CreateDirectory(CurDir);   //该路径不存在时，在当前文件目录下创建文件夹"导出.."

            //不存在该文件时先创建
            String filePath = CurDir + name + ".txt";
            System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePath, false);     //文件已覆盖方式添加内容

            file1.Write(data);                                                              //保存数据到文件

            file1.Close();                                                                  //关闭文件
            file1.Dispose();                                                                //释放对象

            return filePath;
        }

        /// <summary>
        /// 保存数据data到原文件filePathName中
        /// </summary>
        public String SaveToNativeFile(String data, String filePathName, bool mute)
        {
            try
            {
                System.IO.StreamWriter file1 = new System.IO.StreamWriter(filePathName, false); //文件已覆盖方式添加内容
                file1.Write(data);                                                              //保存数据到文件

                file1.Close();                                                                  //关闭文件
                file1.Dispose();                                                                //释放对象

                if (!mute) MessageBox.Show("成功导出数据到:“" + filePathName + "”!");
                return filePathName;
            }
            catch (Exception)
            {
                return SaveToFile(data, "", mute);          //若保存到原文件失败，则创建新文件进行保存
            }
        }

        //=======================================================
        //其他相关功能
        //=======================================================
        /// <summary>
        /// 文件拖进事件处理：
        /// </summary>
        public void dragEnter(DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))    //判断拖来的是否是文件
                e.Effect = DragDropEffects.Link;                //是则将拖动源中的数据连接到控件
            else e.Effect = DragDropEffects.None;
        }
        /// <summary>
        /// 文件放下事件处理：
        /// 放下, 另外需设置对应控件的 AllowDrop = true; 
        /// 获取的文件名形如 "d:\1.txt;d:\2.txt"
        /// </summary>
        public string dragDrop(DragEventArgs e)
        {
            string filesName = "";
            Array file = (System.Array)e.Data.GetData(DataFormats.FileDrop);//将拖来的数据转化为数组存储

            //判断是否为目录，从目录载入文件
            if(file.Length == 1)
            {
                string str = file.GetValue(0).ToString();
                if (!System.IO.File.Exists(str) && System.IO.Directory.Exists(str)) //拖入的不是文件，是文件夹
                {
                    string[] files = System.IO.Directory.GetFiles(str);
                    for (int i = 0; i < files.Length; i++)
                        filesName += (files[i] + (i == files.Length - 1 ? "" : ";"));

                    return filesName;
                }
            }

            //拖入的所有文件
            int len = file.Length;
            for (int i = 0; i < len; i++)
            {
                filesName += (file.GetValue(i).ToString() + (i == file.Length - 1 ? "" : ";"));
            }

            return filesName;
        }

        /// <summary>
        /// 获取文件中的数据串
        /// </summary>
        public string ToString(String filePath)
        {
            string str = "";

            //获取文件内容
            if (System.IO.File.Exists(filePath))
            {
                System.IO.StreamReader file1 = new System.IO.StreamReader(filePath);//读取文件中的数据
                str = file1.ReadToEnd();                                            //读取文件中的全部数据

                file1.Close();
                file1.Dispose();
            }
            return str;
        }

        /// <summary>
        /// 将字符串转化为数值，默认值为0
        /// </summary>
        public int ToInt(string strNum)
        {
            return ToInt(strNum, 0);
        }
        /// <summary>
        /// 将字符串转化为数值，默认值为defaultNum
        /// </summary>
        public int ToInt(string strNum, int defaultNum)
        {
            try { defaultNum = Int32.Parse(strNum.Trim()); }
            catch (Exception ex) { };
            return defaultNum;
        }

        /// <summary>
        /// 将字符串转化为数值，默认值为0
        /// </summary>
        public float ToFloat(string strNum)
        {
            return ToFloat(strNum, 0);
        }
        /// <summary>
        /// 将字符串转化为数值，默认值为defaultNum
        /// </summary>
        public float ToFloat(string strNum, float defaultNum)
        {
            try { defaultNum = float.Parse(strNum.Trim()); }
            catch (Exception ex) { };
            return defaultNum;
        }

        /// <summary>
        /// 将字符串数字按分割符，分割为数值构成数组
        /// </summary>
        public int[] toIntArray1(string data, char seprator)
        {
            string[] datas = data.Split(seprator);
            int[] num = new int[datas.Length];
            for (int i = 0; i < datas.Length; i++)
                num[i] = ToInt(datas[i]);

            return num;
        }

        /// <summary>
        /// 将字符串转换为二维数组
        /// </summary>
        public int[][] toArray2(string data, char seprator2, char seprator1)
        {
            int[][] num = null;

            string[] datas1 = data.Split(seprator2);              //二维项分割符
            num = new int[datas1.Length][];
            for (int i = 0; i < datas1.Length; i++)
            {
                string[] datas2 = datas1[i].Split(seprator1);     //一维项分割符
                num[i] = new int[datas2.Length];

                for (int j = 0; j < datas2.Length; j++)
                {
                    num[i][j] = ToInt(datas2[j]);
                }
            }

            return num;
        }

        //=======================================================
        //图像剪裁、缩放，转化为鼠标光标
        //=======================================================
        /// <summary>
        /// 从图像pic中截取区域Rect构建新的图像
        /// </summary>
        public Bitmap GetRect(Image pic, Rectangle Rect)
        {
            //创建图像
            Rectangle drawRect = new Rectangle(0, 0, Rect.Width, Rect.Height);  //绘制整块区域
            Bitmap tmp = new Bitmap(drawRect.Width, drawRect.Height);           //按指定大小创建位图

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空
            g.DrawImage(pic, drawRect, Rect, GraphicsUnit.Pixel);   //从pic的给定区域进行绘制

            return tmp;     //返回构建的新图像
        }

        /// <summary>
        /// 从图像pic中截取区域Rect构建为drawRect大小的图像
        /// </summary>
        public Bitmap GetRectTo(Image pic, Rectangle Rect, Rectangle drawRect)
        {
            //创建图像
            Bitmap tmp = new Bitmap(drawRect.Width, drawRect.Height);           //按指定大小创建位图

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空
            g.DrawImage(pic, drawRect, Rect, GraphicsUnit.Pixel);   //从pic的给定区域进行绘制

            return tmp;     //返回构建的新图像
        }

        /// <summary>
        /// 对图像pic进行缩放，缩放比例reSize
        /// </summary>
        public Bitmap shrinkTo(Image pic, float reSize)
        {
            Size S = new Size((int)(pic.Width * reSize), (int)(pic.Height * reSize));
            Rectangle Rect = new Rectangle(new Point(0, 0), S);

            return shrinkTo(pic, Rect);
        }
        /// <summary>
        /// 对图像pic进行缩放处理，缩放为Rect大小的新图像
        /// </summary>
        public Bitmap shrinkTo(Image pic, Rectangle Rect)
        {
            //创建图像
            Bitmap tmp = new Bitmap(Rect.Width, Rect.Height);                   //按指定大小创建位图
            Rectangle drawRect = new Rectangle(0, 0, Rect.Width, Rect.Height);  //绘制整块区域
            Rectangle srcRect = new Rectangle(0, 0, pic.Width, pic.Height);     //pic的整个区域

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空
            g.DrawImage(pic, drawRect, srcRect, GraphicsUnit.Pixel);//从pic的给定区域进行绘制

            return tmp;     //返回构建的新图像
        }

        //Image转化为Bitamap
        public Bitmap ToBitmap(Image pic)
        {
            //创建图像
            Bitmap tmp = new Bitmap(pic.Width, pic.Height);                //按指定大小创建位图
            Rectangle Rect = new Rectangle(0, 0, pic.Width, pic.Height);   //pic的整个区域

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空

            g.DrawImage(pic, Rect, Rect, GraphicsUnit.Pixel);       //从pic的给定区域进行绘制

            return tmp;     //返回构建的新图像
        }


        //获取图像pic旋转angle角度后的图像
        public Bitmap Rotate2(Image pic, float angle)
        {
            Rectangle desRect = getClipRect(pic, angle); //获取图像的大小

            Bitmap tmp = new Bitmap(desRect.Width, desRect.Height);                           //按指定大小创建位图
            Rectangle Rect = new Rectangle(0, 0, pic.Width, pic.Height);   //pic的整个区域

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空

            g.TranslateTransform(Rect.Width / 2, Rect.Height / 2);  //设置为绕中心处旋转
            g.RotateTransform(angle);                               //控制旋转角度
            

            //Point pos = new Point((int)((desRect.Width - pic.Width) / 2), (int)((desRect.Height - pic.Height) / 2));  //中心对齐

            //g.DrawImage(pic, pos);                                  //绘制图像

            g.DrawImage(pic, 0, 0);

            g.TranslateTransform(-Rect.Width / 2, -Rect.Height / 2);//还原锚点为左上角


            ////对图像进行剪裁
            //double angle1 = Math.Atan2(pic.Height, pic.Width);      //获取当前角度
            //double angle2 = Math.PI - angle1;
            //double num = Math.Sqrt(pic.Width * pic.Width + pic.Height * pic.Height);


            //double width1 = num * Math.Abs(Math.Cos(angle1 + angle)), width2 = num * Math.Abs(Math.Cos(angle2 + angle));
            //double height1 = num * Math.Abs(Math.Sin(angle1 + angle)), height2 = num * Math.Abs(Math.Sin(angle2 + angle));
            //int w = width1 > width2 ? (int)width1 : (int)width2, h = height1 > height2 ? (int)height1 : (int)height2;

            //Rectangle clipRect = new Rectangle((int)((size - w) / 2), (int)((size - h) / 2), w, h);
            //tmp = GetRect(tmp, clipRect);

            return tmp;     //返回构建的新图像
        }
        private Rectangle getClipRect(Image pic, float angle)
        {
            //对图像进行剪裁
            double angle1 = Math.Atan2(pic.Height, pic.Width);      //获取当前角度
            double angle2 = Math.PI - angle1;
            double num = Math.Sqrt(pic.Width * pic.Width + pic.Height * pic.Height);


            double width1 = num * Math.Abs(Math.Cos(angle1 + angle)), width2 = num * Math.Abs(Math.Cos(angle2 + angle));
            double height1 = num * Math.Abs(Math.Sin(angle1 + angle)), height2 = num * Math.Abs(Math.Sin(angle2 + angle));
            int w = width1 > width2 ? (int)width1 : (int)width2, h = height1 > height2 ? (int)height1 : (int)height2;

            Rectangle clipRect = new Rectangle(0, 0, w, h);

            return clipRect;
        }

        /// <summary>
        /// 图像沿Y轴翻转
        /// </summary>
        public Bitmap FlipY(Bitmap pic)
        {
            pic.RotateFlip(RotateFlipType.RotateNoneFlipY);
            return pic;
        }

        /// <summary>
        /// 图像沿X轴翻转
        /// </summary>
        public Bitmap FlipX(Bitmap pic)
        {
            pic.RotateFlip(RotateFlipType.RotateNoneFlipX);
            return pic;
        }

        /// <summary>
        /// 对图像进行任意角度的旋转
        /// </summary>
        public Bitmap KiRotate(Bitmap bmp, float angle)
        {
            return KiRotate(bmp, angle, Color.Transparent);
        }
        /// <summary>
        /// 任意角度旋转
        /// </summary>
        /// <param name="bmp">原始图Bitmap</param>
        /// <param name="angle">旋转角度</param>
        /// <param name="bkColor">背景色</param>
        /// <returns>输出Bitmap</returns>
        public Bitmap KiRotate(Bitmap bmp, float angle, Color bkColor)
        {
            int w = bmp.Width + 2;
            int h = bmp.Height + 2;

            PixelFormat pf;

            if (bkColor == Color.Transparent)
            {
                pf = PixelFormat.Format32bppArgb;
            }
            else
            {
                pf = bmp.PixelFormat;
            }

            Bitmap tmp = new Bitmap(w, h, pf);
            Graphics g = Graphics.FromImage(tmp);
            g.Clear(bkColor);
            g.DrawImageUnscaled(bmp, 1, 1);
            g.Dispose();

            GraphicsPath path = new GraphicsPath();
            path.AddRectangle(new RectangleF(0f, 0f, w, h));
            Matrix mtrx = new Matrix();
            mtrx.Rotate(angle);
            RectangleF rct = path.GetBounds(mtrx);

            Bitmap dst = new Bitmap((int)rct.Width, (int)rct.Height, pf);
            g = Graphics.FromImage(dst);
            g.Clear(bkColor);
            g.TranslateTransform(-rct.X, -rct.Y);
            g.RotateTransform(angle);
            g.InterpolationMode = InterpolationMode.HighQualityBilinear;
            g.DrawImageUnscaled(tmp, 0, 0);
            g.Dispose();

            tmp.Dispose();

            return dst;
        }

        //获取图像pic旋转angle角度后的图像
        public Bitmap Rotate(Image pic, float angle)
        {
            //创建图像
            int size = pic.Width > pic.Height ? pic.Width * 3 : pic.Height * 3;

            Bitmap tmp = new Bitmap(size, size);                           //按指定大小创建位图
            Rectangle Rect = new Rectangle(0, 0, pic.Width, pic.Height);   //pic的整个区域

            //绘制
            Graphics g = Graphics.FromImage(tmp);                   //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));                    //清空

            g.TranslateTransform(Rect.Width / 2, Rect.Height / 2);  //设置为绕中心处旋转
            g.RotateTransform(angle);                               //控制旋转角度

            Point pos = new Point((int)((size - pic.Width) / 2), (int)((size - pic.Height) / 2));  //中心对齐
            g.DrawImage(pic, pos);                                  //绘制图像

            g.TranslateTransform(-Rect.Width / 2, -Rect.Height / 2);//还原锚点为左上角


            ////对图像进行剪裁
            //double angle1 = Math.Atan2(pic.Height, pic.Width);      //获取当前角度
            //double angle2 = Math.PI - angle1;
            //double num = Math.Sqrt(pic.Width * pic.Width + pic.Height * pic.Height);


            //double width1 = num * Math.Abs(Math.Cos(angle1 + angle)), width2 = num * Math.Abs(Math.Cos(angle2 + angle));
            //double height1 = num * Math.Abs(Math.Sin(angle1 + angle)), height2 = num * Math.Abs(Math.Sin(angle2 + angle));
            //int w = width1 > width2 ? (int)width1 : (int)width2, h = height1 > height2 ? (int)height1 : (int)height2;

            //Rectangle clipRect = new Rectangle((int)((size - w) / 2), (int)((size - h) / 2), w, h);
            //tmp = GetRect(tmp, clipRect);

            return tmp;     //返回构建的新图像
        }


        /// <summary>
        /// 从给定的图像创建鼠标光标
        /// </summary>
        public Cursor GetCursor(Bitmap pic)
        {
            try { return new Cursor(pic.GetHicon()); }         //从位图创建鼠标图标
            catch (Exception e) { return Cursors.Default; }
        }

        /// <summary>
        /// 获取用图像pic，按指定大小width创建鼠标光标
        /// </summary>
        public Cursor GetCursor(Image pic, int width)
        {
            Bitmap icon = new Bitmap(width, width);             //按指定大小创建位图
            Graphics g = Graphics.FromImage(icon);              //从位图创建Graphics对象
            g.Clear(Color.FromArgb(0, 0, 0, 0));
            g.DrawImage(pic, 0, 0, icon.Width, icon.Height);    //绘制Image到位图

            //Bitmap icon = new Bitmap(tiles[toolsPostion.Y - 1]);

            try { return new Cursor(icon.GetHicon()); }         //从位图创建鼠标图标
            catch (Exception e) { return Cursors.Default; }
        }


        //=======================================================
        //XML文件的，数据读、写
        //=======================================================

        /// <summary>
        /// 读取XML
        /// </summary>
        public void ReadXML(string file)
        {   //using System.Xml;

            //载入XML文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(file);


            XmlNode root = xmlDoc.SelectSingleNode("Map");//查找<bookstore>
            XmlElement Node = (XmlElement)root;
            string str = Node.GetAttribute("CellHeight"); //CellWidth

            MessageBox.Show("宽度值：" + str + "", "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);

            //root.SelectSingleNode()
            XmlNode Node2 = root.SelectSingleNode("PhysicalLayer");        //查找子节点
            XmlElement Elem = (XmlElement)Node2;
            MessageBox.Show("获取数据：" + Elem.InnerText, "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);

        }

        /// <summary>
        /// 写入XML
        /// </summary>
        public void writeXML(string file)
        {
            //载入XML文档
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(file);

            //修改XML
            XmlNode root = xmlDoc.SelectSingleNode("bookstore");//查找<bookstore>
            {
                XmlElement xe1 = xmlDoc.CreateElement("book");  //创建一个<book>节点
                xe1.SetAttribute("genre", "李赞红");            //设置该节点genre属性
                xe1.SetAttribute("ISBN", "2-3631-4");           //设置该节点ISBN属性
                {
                    XmlElement xesub1 = xmlDoc.CreateElement("title");
                    xesub1.InnerText = "CS从入门到精通";        //设置文本节点
                    xe1.AppendChild(xesub1);                    //添加到<book>节点中

                    XmlElement xesub2 = xmlDoc.CreateElement("author");
                    xesub2.InnerText = "候捷";
                    xe1.AppendChild(xesub2);

                    XmlElement xesub3 = xmlDoc.CreateElement("price");
                    xesub3.InnerText = "58.3";
                    xe1.AppendChild(xesub3);
                }
                root.AppendChild(xe1);                          //添加到<bookstore>节点中
            }

            //保存修改到XML
            xmlDoc.Save(file);
            MessageBox.Show("写入XML完成", "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        

        /// <summary>
        /// 获取XML文件，节点属性值,用法：
        /// ReadXML_Attrribute("D:\\data.XML", "Map", "CellHeight");     根节点
        /// ReadXML_Attrribute("D:\\data.XML", "Map/BuildItem", "name"); 子节点
        /// </summary>
        public string ReadXML_NodeAttrribute(string file, string nodePath, string attr)
        {   //using System.Xml;

            string str = "";
            try
            {
                //载入XML文档
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(file);

                XmlNode Node = xmlDoc.SelectSingleNode(nodePath);   //查找节点
                XmlNode Node2 = xmlDoc.SelectNodes(nodePath)[2];
                Node = Node2;
                XmlElement Elemnet = (XmlElement)Node;              //转化为XML元素

                str = Elemnet.GetAttribute(attr);                   //获取节点属性值
            }
            catch (Exception e)
            {
                string tmp = "获取XML文件，节点属性值出错！ \n1、请确保文件\n“" + file + "”存在，且其格式无误\n2、请确保节点“" + nodePath + "”和节点属性“" + attr + "”在XML文件中确实存在";
                MessageBox.Show(tmp, "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            return str;
        }

        /// <summary>
        /// 读取所有节点nodePath,的所有attr属性值
        /// </summary>
        public string[][] ReadXML_NodesAttrribute(string file, string nodePath, string[] attr)
        {   //using System.Xml;

            string[][] str = null;
            try
            {
                //载入XML文档
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(file);

                XmlNodeList Nodes = xmlDoc.SelectNodes(nodePath);       //获取所有nodePath的节点
                str = new string[Nodes.Count][];

                for (int i = 0; i < Nodes.Count; i++)
                {
                    XmlElement Elemnet = (XmlElement)Nodes[i];          //转化为XML元素
                    str[i] = new string[attr.Length];

                    for (int j = 0; j < attr.Length; j++)
                        str[i][j] = Elemnet.GetAttribute(attr[j]);      //获取节点属性值
                }
            }
            catch (Exception e)
            {
                string tmp = "获取XML文件，节点属性值出错！ \n1、请确保文件\n“" + file + "”存在，且其格式无误\n2、请确保节点“" + nodePath + "”和节点属性“" + attr + "”在XML文件中确实存在";
                MessageBox.Show(tmp, "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            return str;
        }

        /// <summary>
        /// 读取所有节点nodePath,的所有attr属性值
        /// </summary>
        public string[][] ReadXML_NodesAttrribute2(string fileText, string nodePath, string[] attr)
        {   //using System.Xml;

            string[][] str = null;
            try
            {
                //载入XML文档
                XmlDocument xmlDoc = new XmlDocument();
                //xmlDoc.Load(file);
                xmlDoc.LoadXml(fileText);

                XmlNodeList Nodes = xmlDoc.SelectNodes(nodePath);       //获取所有nodePath的节点
                str = new string[Nodes.Count][];

                for (int i = 0; i < Nodes.Count; i++)
                {
                    XmlElement Elemnet = (XmlElement)Nodes[i];          //转化为XML元素
                    str[i] = new string[attr.Length];

                    for (int j = 0; j < attr.Length; j++)
                        str[i][j] = Elemnet.GetAttribute(attr[j]);      //获取节点属性值
                }
            }
            catch (Exception e)
            {
                string tmp = "获取XML文件，节点属性值出错！ \n1、请确保XML文件\n" + "存在，且其格式无误\n2、请确保节点“" + nodePath + "”和节点属性“" + attr + "”在XML文件中确实存在";
                MessageBox.Show(tmp, "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            return str;
        }
        
        /// <summary>
        ///获取XML文件，节点数据,用法
        ///ReadXML_NodeText("D:\\data.XML", "Map");                  根节点
        ///ReadXML_NodeText("D:\\data.XML", "Map/PhysicalLayer");    子节点
        /// </summary>
        public string ReadXML_NodeText(string file, string nodePath)
        {
            string str = "";
            try
            {
                //载入XML文档
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(file);

                XmlNode Node = xmlDoc.SelectSingleNode(nodePath);   //查找节点
                XmlElement Elemnet = (XmlElement)Node;              //转化为XML元素

                str = Elemnet.InnerText;                     //获取节点数据
            }
            catch (Exception e)
            {
                string tmp = "获取XML文件，节点数据出错！ \n1、请确保文件\n“" + file + "”存在，且其格式无误\n2、请确保节点“" + nodePath + "”在XML文件中确实存在";
                MessageBox.Show(tmp, "消息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            return str;
        }


    }
}
